Imports Microsoft.Office.Interop
Imports Microsoft.Office.Interop.Access
Imports System.IO
Imports System.Collections.Generic

Public Class FileInfoComparer
    Implements IComparer(Of FileInfo)

    Public Function Compare(ByVal x As System.IO.FileInfo, _
                            ByVal y As System.IO.FileInfo) As Integer _
                        Implements IComparer(Of System.IO.FileInfo).Compare

        Return x.Name.CompareTo(y.Name)

    End Function
End Class

Public MustInherit Class BaseAccessObjectTransformer

    Protected _app As Access.Application
    Protected _baseExportPath As String
    Protected _fileComp As FileInfoComparer

    ''' <summary>
    ''' Holds the names of objects of this type.  This is so that we 
    ''' can keep track of objects in the access database and import 
    ''' only the objects in use.  Overtime, objects maybe renamed and 
    ''' deleted and we do not want to import these object.
    ''' </summary>
    ''' <remarks></remarks>
    Protected _objectList As List(Of IExportedAccessObject)

    Property debugLevel As enumDebugLevel = enumDebugLevel.SUMMARY

    Protected Sub addObjectName(ByVal accExportedObject As IExportedAccessObject)
        If Me._objectList Is Nothing Then
            Me._objectList = New List(Of IExportedAccessObject)
        End If
        Me._objectList.Add(accExportedObject)
    End Sub

    Public Property ObjectList() As List(Of IExportedAccessObject)
        Get
            If Me._objectList Is Nothing Then
                Me._objectList = New List(Of IExportedAccessObject)
            End If
            Return _objectList
        End Get
        Set(ByVal value As List(Of IExportedAccessObject))
            _objectList = value
        End Set
    End Property


    ''' <summary>
    ''' Returns true if the object is in the object list of previously exported objects
    ''' This is so that we import whatever was exported the last time we run the export
    ''' to svn sources
    ''' </summary>
    ''' <param name="accExportedObject"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function importObjectName(ByVal accExportedObject As IExportedAccessObject) As Boolean

        If Me._objectList Is Nothing Then
            Throw New ApplicationException("Object List not loaded!")
        End If

        Return Me._objectList.Contains(accExportedObject)

    End Function


    Public ReadOnly Property fileComparer As FileInfoComparer
        Get
            If _fileComp Is Nothing Then
                _fileComp = New FileInfoComparer()
            End If
            Return _fileComp
        End Get
    End Property

    Public WriteOnly Property App() As Access.Application
        Set(ByVal value As Access.Application)
            _app = value
        End Set
    End Property

    Public WriteOnly Property BaseExportPath() As String
        Set(ByVal value As String)
            _baseExportPath = value

            If IO.Directory.Exists(Me.getExportFolder) = False Then
                IO.Directory.CreateDirectory(Me.getExportFolder)
            End If

        End Set
    End Property

    Protected Overridable Sub Tranform()

        If TypeOf Me Is IAccessColection Then
            Dim coll As AllObjects = CType(Me, IAccessColection).getAccessObjects
            Console.WriteLine("Will export " & coll.Count & " " & Me.getAccessType.ToString)
            For Each accObject As Access.AccessObject In coll

                Console.WriteLine(accObject.Name)

                Me._app.SaveAsText(Me.getAccessType, accObject.Name, _
                                    Me.getObjectFileName(accObject.Name))
                Me.addObjectName(New ExportedAccessObject(accObject.Name, _
                                    CType(Me.getAccessType, SVNAccessObjectType)))

            Next accObject
            Console.WriteLine(" - Done")
        Else
            Throw New ApplicationException("Must override Tranform ")
        End If

    End Sub


    Protected Overridable Sub LoadObjects()

        Dim di As New IO.DirectoryInfo(Me.getExportFolder)
        Dim files As IO.FileInfo() = di.GetFiles("*." & Me.getExtension)
        If files.Length = 0 Then Return

        Array.Sort(files, Me.fileComparer)
        'list the names of all files in the specified directory
        For Each thisFile As IO.FileInfo In files
            Dim oname As String = thisFile.Name.Replace("." & Me.getExtension, "")



            If Not Me.importObjectName( _
                    New ExportedAccessObject(oname, _
                        CType(Me.getAccessType, SVNAccessObjectType))) Then

                'Console.WriteLine("-----------Skipped file:" & oname)
            Else

                Console.WriteLine(oname)

                Try
                    _app.LoadFromText(Me.getAccessType, oname, thisFile.FullName)
                Catch e As Exception
                    Console.WriteLine("Error loading component: " & _
                                      thisFile.FullName & ", Type:" & _
                                        Me.getAccessType.ToString & vbCrLf & _
                                      e.Message)
                    Throw e
                End Try
            End If


        Next

        Console.WriteLine("Done Loading " & Me.getSubfolder)

    End Sub

    Public MustOverride Function getExtension() As String
    Public MustOverride Function getSubfolder() As String

    Public Sub Save()

        Me.Tranform()

    End Sub

    Public Overridable Sub Load()

        Me.LoadObjects()

    End Sub

    Public Function getExportFolder() As String

        Return _baseExportPath & "\" & Me.getSubfolder & "\"

    End Function

    Public Function getObjectFileName(ByVal oname As String) As String

        Return getExportFolder() & oname & "." & Me.getExtension

    End Function

    Protected MustOverride Function getAccessType() As AcObjectType

End Class
